package cn.kmsoft.jssc.service;

import cn.kmsoft.jssc.entity.analyse.AnalyseTaskParam;
import cn.kmsoft.jssc.entity.analyse.ExchangeResultEnvelope;
import cn.kmsoft.jssc.entity.analyse.TaskResult;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import lombok.extern.slf4j.Slf4j;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.http.HttpEntity;
import org.springframework.http.HttpMethod;
import org.springframework.http.ResponseEntity;
import org.springframework.web.client.RestTemplate;

import java.util.*;
import java.util.concurrent.Callable;

@Slf4j
public abstract class AnalyseTaskProcessor implements Callable<TaskResult> {
    //private static final Logger logger = LoggerFactory.getLogger(AnalyseTaskProcessor.class);

    protected final int maxAnalystCount = 5;//最多分析次数

    @Override
    public TaskResult call() throws Exception {
        // TODO Auto-generated method stub
        String threadId = Thread.currentThread().getName();
        System.out.println("Thread: "+threadId+" is doing it!");

        //第二阶段——等待所有选手准备好
        Random random = new Random();
        int result = random.nextInt(100);

        //分析
        TaskResult taskResult = new TaskResult();

        return taskResult;
    }


    /**
     * 转发请求到SpatialBoot后台叠加分析的服务
     *
     * @param targetUrl
     * @param entity
     * @return
     */
    protected ResponseEntity<JSONObject> exchangeSpatialAnalyst(String jobId, String targetUrl, HttpEntity<String> entity) {
        RestTemplate restTemplate = new RestTemplate();
        ResponseEntity<JSONObject> exchange = null;

        try {
            exchange = restTemplate.exchange(targetUrl, HttpMethod.POST, entity, JSONObject.class);
        } catch (Exception ex) {
            String error = ex.getMessage();
            String errorMsg=String.format("--->提交spatialboot后台分析发生异常，jobId: %s, targetUrl: %s，错误信息：%s", jobId,targetUrl, error);
            System.out.println(errorMsg);

            log.error(errorMsg);
        }

        return exchange;
    }
    protected ResponseEntity<JSONObject> exchangeSpatialAnalystByLoop(String jobId, String targetUrl, HttpEntity<String> entity){
        RestTemplate restTemplate = new RestTemplate();
        int loopSize=0;
        boolean bSuccessed=false;
        ResponseEntity<JSONObject> exchange=null;
        do {
            try {
                if(loopSize>0) {
                    String loopMsg = String.format("--->重复第 %d 次提交spatialboot后台分析，jobId: %s, targetUrl: %s", loopSize, jobId, targetUrl);
                    System.out.println(loopMsg);
                    log.info(loopMsg);
                }
                exchange = restTemplate.exchange(targetUrl, HttpMethod.POST, entity, JSONObject.class);
                if(exchange == null){
                    String failedMsg = String.format("--->提交spatialboot后台分析失败，jobId: %s, loopSize：%d ,targetUrl: %s", jobId, loopSize, targetUrl);
                    System.out.println(failedMsg);
                    log.error(failedMsg);
                }else {
                    //后台执行成功
                    bSuccessed = true;
                }
            }catch (Exception ex){
                String error = ex.getMessage();
                String errorMsg = String.format("--->提交spatialboot后台分析发生异常，jobId: %s, loopSize：%d ,targetUrl: %s，详细信息：%s", jobId, loopSize, targetUrl, error);
                System.out.println(errorMsg);

                log.error(errorMsg);
            }

            loopSize++;
        }while ( bSuccessed==false && loopSize<= maxAnalystCount);

        return exchange;
    }

    protected ExchangeResultEnvelope exchangeSpatialAnalystByLoopEx(String jobId, String targetUrl, HttpEntity<String> entity){
        RestTemplate restTemplate = new RestTemplate();

        ExchangeResultEnvelope resultEnvelope= new ExchangeResultEnvelope(jobId);
        int loopSize=0;
        boolean bSuccessed=false;
        ResponseEntity<JSONObject> exchange=null;
        do {
            try {
                if(loopSize>0) {
                    String loopMsg = String.format("--->重复第 %d 次提交spatialboot后台分析，jobId: %s, targetUrl: %s", loopSize, jobId, targetUrl);
                    System.out.println(loopMsg);
                    log.info(loopMsg);
                }
                exchange = restTemplate.exchange(targetUrl, HttpMethod.POST, entity, JSONObject.class);
                if(exchange == null){
                    String failedMsg = String.format("--->提交spatialboot后台分析失败，jobId: %s, loopSize：%d ,targetUrl: %s", jobId, loopSize, targetUrl);
                    System.out.println(failedMsg);
                    log.error(failedMsg);
                }else {
                    //后台执行成功
                    bSuccessed = true;
                }
            }catch (Exception ex){
                String error = ex.getMessage();
                String errorMsg=String.format("--->提交spatialboot后台分析发生异常，jobId: %s, loopSize：%d ,targetUrl: %s，详细信息：%s", jobId, loopSize, targetUrl, error);
                System.out.println(errorMsg);
                log.error(errorMsg);
            }

            loopSize++;
        }while ( bSuccessed==false && loopSize<= this.maxAnalystCount);

        resultEnvelope.setExchange(exchange);
        resultEnvelope.setbSuccessed(bSuccessed);

        return resultEnvelope;
    }

    /**
     * 只解析要素的属性信息
     *
     * @param features
     * @return
     */
    public List<Map<String,String>> parseFeaProperties(JSONArray features) {
        List<Map<String,String>> allFeaProperties = new ArrayList<Map<String,String>>();

        int feaCount = features.size();
        for(int n=0; n<feaCount; n++) {
            JSONObject feaJObject = features.getJSONObject(n);
            //解析属性信息
            JSONObject propObject = feaJObject.getJSONObject("properties");
            Map<String,String> feaProperties = new HashMap<String,String>();
            for (Map.Entry<String, Object> entry : propObject.entrySet()) {
                String fieldName = entry.getKey();
                String fieldValue = entry.getValue() != null ? entry.getValue().toString():"";

                //System.out.println(fieldName + ":" + fieldValue);
                feaProperties.put(fieldName, fieldValue);
            }

            allFeaProperties.add(feaProperties);
        }

        return allFeaProperties;
    }

    /**
     * 解析要素的图形坐标和属性信息，图形坐标的key为geom
     * @param features
     * @return
     */
    public List<Map<String,String>> parseFeaGeometryAndProperties(JSONArray features) {
        List<Map<String,String>> allFeaProperties = new ArrayList<Map<String,String>>();

        int feaCount = features.size();
        for(int n=0; n<feaCount; n++) {
            JSONObject feaJObject = features.getJSONObject(n);

            //1-解析属性信息
            JSONObject propObject = feaJObject.getJSONObject("properties");
            Map<String,String> feaProperties = new HashMap<String,String>();
            for (Map.Entry<String, Object> entry : propObject.entrySet()) {
                String fieldName = entry.getKey();
                String fieldValue = entry.getValue() != null ? entry.getValue().toString():"";

                //System.out.println(fieldName + ":" + fieldValue);
                feaProperties.put(fieldName, fieldValue);
            }
            //2-解析图形坐标
            JSONObject geomObject = feaJObject.getJSONObject("geometry");
            //System.out.println(String.format("--->id: %d, geom: %s ",n+1, geomObject.toJSONString()));
            feaProperties.put("geom",geomObject.toJSONString());

            allFeaProperties.add(feaProperties);
        }

        return allFeaProperties;
    }


    /**
     * 开始执行分析
     *
     * @param operatorMethod
     * @param threadId
     * @param param
     * @return
     */
    public abstract TaskResult startAnalyse(String operatorMethod,String threadId, AnalyseTaskParam param);


}
